/*
 * Author: xiguan
 * Mail: xiguan.teng@qq.com
 * -----
 * Last Modified: 2022-06-04 16:38:44
 * Modified By: xiguan
 * -----
 * Copyright (c) 2022 XiGuan Inc.
 * 
 * No Bug No error No warning.
 */



#include <bits/stdc++.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <signal.h>
#include <time.h>
#include <syslog.h>
#include <sys/param.h>

using namespace std;

int init_daemon(void){
    pid_t pid;
    int i;

    // 忽略终端I/O信号，STOP信号
    signal(SIGTTOU, SIG_IGN);
    signal(SIGTTIN, SIG_IGN);
    signal(SIGTSTP, SIG_IGN);
    signal(SIGHUP, SIG_IGN);

    pid = fork();

    // 父进程 结束他
    if(pid > 0){
        exit(0);
    }
    else if(pid == -1){
        perror("fork 1");
        return -1;
    }

    // 建立一个新的进程组，在这个新的进程组中，子进程成为这个进程组的首进程，以使进程脱离所有终端
    setsid();
    // 再建立一个子进程，退出父进程，保证该进程不是进程组长，同时让该进程无法再打开一个新的终端
    pid = fork();
    if(pid > 0){
        exit(0);
    } else if(pid == -1){
        perror("fork 2");
        return -1;
    }

    // 关闭所有从父进程复制过来不再需要的文件描述符
    for(i = 0; i < NOFILE; close(i ++));
    // 改变当前工作目录
    chdir("/");
    // 设置文件屏蔽字段0
    umask(0);
    // 忽略SIGCHLD信号
    signal(SIGCHLD, SIG_IGN);
    return 0;
}


int main(int argc, char *argv[]){

    time_t now;
    init_daemon();
    syslog(LOG_USER|LOG_INFO, "测试守护进程! \n");
    while(1){
        sleep(0);
        time(&now);
        syslog(LOG_USER|LOG_INFO, "系统时间： \t%s\t\t\n", ctime(&now));
    }
    
    return 0;
}